package org.syncsoft.overalt.gui.impl.window.shareFolder;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import javax.swing.ComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.JTextComponent;

import org.syncsoft.overalt.common.api.Resource;
import org.syncsoft.overalt.domain.community.entity.Community;
import org.syncsoft.overalt.domain.folder.entity.TypeShare;
import org.syncsoft.overalt.domain.tag.entity.Tag;
import org.syncsoft.overalt.domain.user.entity.User;
import org.syncsoft.overalt.gui.api.JValuedCheckBox;
import org.syncsoft.overalt.gui.api.WindowContextValue;
import org.syncsoft.overalt.gui.api.window.AbstractWindow;
import org.syncsoft.overalt.gui.impl.componentPlugin.CheckBoxComponentPlugin;
import org.syncsoft.overalt.gui.impl.componentPlugin.ComboBoxComponentPlugin;
import org.syncsoft.overalt.gui.impl.componentPlugin.TableUserComponentPlugin;
import org.syncsoft.overalt.gui.impl.tableDataModel.UserTableDataModel;
import org.syncsoft.overalt.gui.util.BuildFormWindow;

/**
 *  
 * @author tptfc
 *
 */
public class ShareFolderWindow extends AbstractWindow {
	private Map<TypeShare, JComponent> panels;
	
	private Collection<User> contacts;
	private Collection<Community> communities;
	{
		setPanels(new HashMap<TypeShare, JComponent>());
		setContacts(new HashSet<User>());
		setCommunities(new HashSet<Community>());
	}

	public ShareFolderWindow(ShareFolderWindowControll controller) {
		super(controller);
	}

	public ShareFolderWindow(int width, int height, ShareFolderWindowControll controller) {
		super(width, height, controller);
	}

	/*
	 * (non-Javadoc)
	 * @see org.syncsoft.overalt.gui.swing.api.AbstractWindow#buildWindow()
	 */
	@Override
	protected void buildWindow() {
		setTitle(Resource.getProperty("overalt.label.addFile"));
		BuildFormWindow build = new BuildFormWindow(getPanel());
		
		JLabel label;

		label = new JLabel(Resource.getProperty("overalt.text.share.type"));
		
		Collection<TypeShare> items = new ArrayList<TypeShare>();
		items.add(TypeShare.MY_FILES);
		items.add(TypeShare.CONTACTS_FILE);
		items.add(TypeShare.COMMUNITY_FILES);
		
		JComboBox comboBox = newComboBox("typeShare", items);
		comboBox.addActionListener(new ChangePanel(comboBox));
		build.add(label, comboBox);
		
		JComponent myFiles = createMyFilesPanel();
		getPanels().put(TypeShare.MY_FILES, myFiles);
		build.add(myFiles);
		
		JComponent contactsFiles = createContactsFilesPanel();
		getPanels().put(TypeShare.CONTACTS_FILE, contactsFiles);
		build.add(contactsFiles);
		
		JComponent communitiesFiles = createCommunityFilesPanel();
		getPanels().put(TypeShare.COMMUNITY_FILES, communitiesFiles);
		build.add(communitiesFiles);
		
		label = new JLabel(Resource.getProperty("overalt.label.tags"));
		build.add(label, newTextField("tags"));
		
		updateCommunityMembersTable();
		
		addSaveAndCancelButtons(build);
	}
	
	/**
	 * 
	 * @return
	 */
	private JComponent createMyFilesPanel() {
		BuildFormWindow build = new BuildFormWindow();
		
		JLabel label = new JLabel(Resource.getProperty("overalt.label.action") + ":");
		JCheckBox checkBox = newCheckbox("autoTitleAndDescription", Resource.getProperty("overalt.text.automatic.text.and.description"));
		
		build.add(label, checkBox);
		
		JComponent component = build.build();
		component.setVisible(true);
		return component;
	}

	/**
	 * 
	 * @return
	 */
	private JComponent createContactsFilesPanel() {
		BuildFormWindow build = new BuildFormWindow();
		
		JLabel label = new JLabel(Resource.getProperty("overalt.label.contacts"));
		JTable contactsTable = newTableUser("contacts", getContacts());
		
		build.add(label, contactsTable);
		
		JComponent component = build.build();
		component.setVisible(false);
		return component;
	}

	/**
	 * 
	 * @return
	 */
	private JComponent createCommunityFilesPanel() {
		BuildFormWindow build = new BuildFormWindow();
		
		JLabel label = new JLabel(Resource.getProperty("overalt.label.communities"));
		JComboBox comboBox = newComboBox("community", getCommunities());
		
		build.add(label, comboBox);
		
		JValuedCheckBox checkBox = newCheckbox("isMemberCommunity", Resource.getProperty("overalt.text.isMemberCommunity"));
		build.add(checkBox);
		
		JComponent communityMembersComponent = createMembersCommunityPanel();
		build.add(communityMembersComponent);
		
		comboBox.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				updateCommunityMembersTable();
			}
		});
		
		checkBox.addChangeListener(new ChangeIsMemberCommunity(checkBox, communityMembersComponent));
		
		JComponent component = build.build();
		component.setVisible(false);
		return component;
	}
	
	/**
	 * update community members
	 */
	private void updateCommunityMembersTable() {
		UserTableDataModel userDataModel = getComponentPlugin(TableUserComponentPlugin.class).getEntityDataModel("communityMembers");
		JComboBox comboBox = getComponentPlugin(ComboBoxComponentPlugin.class).getComboBox("community");
		Community community = (Community) comboBox.getSelectedItem();
		
		userDataModel.setEntities(community.getMembers());

		JTable table = getComponentPlugin(TableUserComponentPlugin.class).getTable("communityMembers");
		table.getColumnModel().getColumn(0).setMaxWidth(30);
	}
	
	/**
	 * 
	 * @author tptfc
	 *
	 */
	private class ChangeIsMemberCommunity implements ChangeListener {
		private JCheckBox check;
		private JComponent component;
		
		public ChangeIsMemberCommunity(JCheckBox check, JComponent component) {
			setCheck(check);
			setComponent(component);
		}
		
		@Override
		public void stateChanged(ChangeEvent e) {
			if (getCheck().isSelected()) {
				getComponent().setVisible(true);
			} else {
				getComponent().setVisible(false);
			}
		}

		protected JCheckBox getCheck() {
			return check;
		}

		protected void setCheck(JCheckBox check) {
			this.check = check;
		}

		protected JComponent getComponent() {
			return component;
		}

		protected void setComponent(JComponent component) {
			this.component = component;
		}
		
	}
	
	/**
	 * 
	 * @return
	 */
	private JComponent createMembersCommunityPanel() {
		BuildFormWindow build = new BuildFormWindow();
		
		JLabel label = new JLabel(Resource.getProperty("overalt.label.members"));
		JTable membersTable = newTableUser("communityMembers", new HashSet<User>());
		
		build.add(label, membersTable);
		
		JComponent component = build.build();
		component.setVisible(false);
		return component;
	}
	
	/**
	 * 
	 * @author tptfc
	 *
	 */
	private class ChangePanel implements ActionListener {
		private JComboBox comboBox;
		
		public ChangePanel(JComboBox comboBox) {
			setComboBox(comboBox);
		}
		
		@Override
		public void actionPerformed(ActionEvent e) {
			JComponent component = getPanels().get(getComboBox().getSelectedItem());
			
			for (JComponent components : getPanels().values()) {
				components.setVisible(false);
			}
			
			if (component != null) {
				component.setVisible(true);
			}
		}

		protected JComboBox getComboBox() {
			return comboBox;
		}

		protected void setComboBox(JComboBox comboBox) {
			this.comboBox = comboBox;
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.syncsoft.overalt.gui.api.window.AbstractWindow#update(org.syncsoft.overalt.gui.api.WindowContextValue)
	 */
	@Override
	public void update(WindowContextValue context) {
		TypeShare typeShare = context.getValue("typeShare");
		
		if (typeShare != null) {
			JComboBox communityComboBox = getComponentPlugin(ComboBoxComponentPlugin.class).getComboBox("typeShare");
			ComboBoxModel model = communityComboBox.getModel();
			
			model.setSelectedItem(typeShare);
		}
		
		Boolean autoTitleAndDescription = context.getValue("autoTitleAndDescription");
		
		updateDefaultView(autoTitleAndDescription);
		updateContactView(context);
		updateCommunityView(context);
		updateTags(context);
	}

	/**
	 * 
	 * @param autoTitleAndDescription
	 */
	private void updateDefaultView(Boolean autoTitleAndDescription) {
		if (autoTitleAndDescription != null && autoTitleAndDescription) {
			JCheckBox check = getComponentPlugin(CheckBoxComponentPlugin.class).getCheckBox("autoTitleAndDescription");
			check.setSelected(true);
		}
	}

	/**
	 * 
	 * @param context
	 */
	private void updateCommunityView(WindowContextValue context) {
		Community community = context.getValue("community");
		
		if (community != null) {
			JComboBox communityComboBox = getComponentPlugin(ComboBoxComponentPlugin.class).getComboBox("community");
			ComboBoxModel model = communityComboBox.getModel();
			
			for (int i = 0; i < model.getSize(); i++) {
				Object selected = model.getElementAt(i);
				if (selected.equals(community)) {
					model.setSelectedItem(selected);
					break;
				}
			}
		}
		
		Boolean isMemberCommunity = context.getValue("isMemberCommunity");
		
		if (isMemberCommunity != null && isMemberCommunity) {
			JValuedCheckBox checkBox = getComponentPlugin(CheckBoxComponentPlugin.class).getCheckBox("isMemberCommunity");
			checkBox.setSelected(true);
			
			UserTableDataModel userDataModel = getComponentPlugin(TableUserComponentPlugin.class).getEntityDataModel("communityMembers");
			Collection<User> requiredEntities = context.getValue("selectedCommunityMembers");
			
			if (requiredEntities != null) {
				userDataModel.setRequiredEntities(requiredEntities);
			}
		}
	}
	
	/**
	 * 
	 * @param context
	 */
	private void updateContactView(WindowContextValue context) {
		Collection<User> requiredEntities = context.getValue("selectedContacts");
		
		if (requiredEntities != null) {
			UserTableDataModel userDataModel = getComponentPlugin(TableUserComponentPlugin.class).getEntityDataModel("contacts");
			
			if (requiredEntities != null) {
				userDataModel.setRequiredEntities(requiredEntities);
			}
		}
	}
	
	private void updateTags(WindowContextValue context) {
		Collection<Tag> requiredTags = context.getValue("requiredTags");
		
		if (requiredTags != null) {
			JTextComponent textTags = getTextComponent("tags");
			String stringTags = "";
			for (Tag tag : requiredTags) {
				stringTags += tag.getDescription() + ", ";
			}
			
			textTags.setText(stringTags);
		}
	}
	
	/**
	 * 
	 * @param key
	 * @param name
	 * @return
	 */
	private JValuedCheckBox newCheckbox(String key, String name) {
		return getComponentPlugin(CheckBoxComponentPlugin.class).newCheckBox(key, name);
	}
	
	/**
	 * 
	 * @param key
	 * @param users
	 * @return
	 */
	private JTable newTableUser(String key, Collection<User> users) {
		return getComponentPlugin(TableUserComponentPlugin.class).newTable(key, users);
	}

	private Map<TypeShare, JComponent> getPanels() {
		return panels;
	}
	private void setPanels(Map<TypeShare, JComponent> panels) {
		this.panels = panels;
	}

	Collection<User> getContacts() {
		return contacts;
	}
	void setContacts(Collection<User> contacts) {
		this.contacts = contacts;
	}
	Collection<Community> getCommunities() {
		return communities;
	}
	void setCommunities(Collection<Community> communities) {
		this.communities = communities;
	}
}
	
